.rendered_markdown {
    & p {
        margin: 0 0 var(--markdown-interelement-space-px);
    }

    /* The spacing between two paragraphs is double the usual value.
       We coordinate this spacing matches so that it matches the
       spacing between paragraphs in two consecutive 1-line messages. */
    & p + p {
        margin-top: var(--markdown-interelement-doubled-space-px);
    }

    & ul {
        margin: 0 0 var(--markdown-interelement-space-px) 20px;
    }

    /* Swap the left and right margins of bullets for Right-To-Left languages */
    &.rtl ul {
        margin-right: 20px;
        margin-left: 0;
    }

    & ol {
        margin: 0 0 var(--markdown-interelement-space-px) 20px;
    }

    /* Swap the left and right margins of ordered list for Right-To-Left languages */
    &.rtl ol {
        margin-right: 8px;
        margin-left: 0;
    }

    & hr {
        border-bottom: 1px solid hsl(0deg 0% 87%);
        border-top: 1px solid hsl(0deg 0% 87%);
        /* Override Bootstrap with doubled interelement space */
        margin: calc(var(--markdown-interelement-space-px) * 2) 0;

        &:first-child {
            /* When a horizontal rule opens a message, or any other
               area in the message area (e.g., spoilers), there
               should be no space above the rule. */
            margin-top: 0;
        }
    }

    /* Headings */
    & h1,
    h2,
    h3,
    h4,
    h5,
    h6 {
        font-weight: 600;
        line-height: 1.4;
        /* Headings take a margin-top because of the pronounced extra
           space they require, but are zeroed out below when they open
           a message. */
        margin-top: 15px;
        margin-bottom: var(--markdown-interelement-space-px);
    }

    /* Headings: Ensure that messages that start with a heading don't have
       a weirdly blank area at the very start of the message. */
    & h1:first-child,
    h2:first-child,
    h3:first-child,
    h4:first-child,
    h5:first-child,
    h6:first-child {
        margin-top: 0;
    }

    /* We use a modest progression of heading sizes to make them stand out
       from normal next but avoid taking up too much space. */
    & h1 {
        font-size: 1.4em;
    }

    & h2 {
        font-size: 1.3em;
    }

    & h3 {
        font-size: 1.2em;
    }

    & h4 {
        font-size: 1.1em;
    }

    & h5 {
        font-size: 1.05em;
    }

    & h6 {
        font-size: 1em;
    }

    /* Formatting for blockquotes */
    & blockquote {
        padding-left: 5px;
        margin: 0 0 var(--markdown-interelement-space-px) 10px;
        border-left: 5px solid hsl(0deg 0% 87%);
    }

    &.rtl blockquote {
        padding-left: unset;
        padding-right: 5px;
        margin-left: unset;
        margin-right: 10px;
        border-left: unset;
        border-right: 5px solid hsl(0deg 0% 87%);
    }

    /* Formatting for Markdown tables */
    & table {
        padding-right: 10px;
        margin: 0 5px var(--markdown-interelement-space-px);
        width: 99%;
        display: block;
        max-width: fit-content;
        overflow-x: auto;
        white-space: nowrap;
        border-collapse: collapse;
    }

    & thead {
        background-color: var(--color-background-rendered-markdown-thead);
    }

    & tr {
        display: table-row;
        vertical-align: inherit;
    }

    & tr th {
        border: 1px solid var(--color-border-rendered-markdown-table);
        padding: 4px;
        text-align: left;
    }

    & tr td {
        border: 1px solid var(--color-border-rendered-markdown-table);
        padding: 4px;
    }

    /* Emoji; sized to be easily understood while not overwhelming text. */
    .emoji {
        /* The box for emoji is allowed to be larger than the size of the
           line-height. */
        height: var(--length-line-oversize-block);
        width: var(--length-line-oversize-block);
        /* A negative top and bottom margin adjustment allows emoji
           to size larger than the size of the line, without disturbing
           the surrounding lines of text. */
        margin: var(--length-line-oversize-block-margin-adjust) auto;
        /* We set the alignment programmatically, as an em value.
           Because the negative margins above are equal, top and bottom,
           this vertical offset value works without adjustment for
           oversize emoji blocks. */
        vertical-align: var(--line-fitted-vertical-align-offset-em);
    }

    /* Mentions and alert words */
    .user-group-mention,
    .user-mention,
    .topic-mention {
        padding: 0 3px;
        border-radius: 3px;
        white-space: nowrap;
        display: inline-block;
    }

    .user-mention {
        color: var(--color-text-other-mention);
        background-color: var(--color-background-text-direct-mention);

        &.user-mention-me {
            color: var(--color-text-self-direct-mention);
            font-weight: 600;
        }

        &:hover {
            background-color: var(--color-background-text-hover-direct-mention);
        }
    }

    .user-mention[data-user-id="*"],
    .user-group-mention,
    .topic-mention {
        color: var(--color-text-other-mention);
        background-color: var(--color-background-text-group-mention);

        &.user-mention-me {
            color: var(--color-text-self-group-mention);
            font-weight: 600;
        }
    }

    .stream-topic {
        /* Display whitespace within topics. */
        white-space: pre-wrap;
    }

    .user-group-mention {
        &:hover {
            background-color: var(--color-background-text-hover-group-mention);
        }
    }

    .alert-word {
        background-color: var(--color-background-alert-word);
    }

    /* Timestamps */
    & time {
        display: inline-flex;
        align-items: baseline;
        gap: 3px;
        background: hsl(0deg 0% 93%);
        border-radius: 3px;
        padding: 0 0.2em;
        box-shadow: 0 0 0 1px hsl(0deg 0% 80%);
        white-space: nowrap;
        margin: 0 2px 1px;

        .markdown-timestamp-icon {
            align-self: center;
        }
    }

    /* LaTeX styling */
    .katex-display {
        /* KaTeX sometimes overdraws its bounding box by a little, so we
           enlarge its scrolling area by adding 3px of padding to its top
           and bottom. To prevent what will appear as extra whitespace,
           we reduce surrounding margins by the same 3px. */
        padding: 3px 0;
        margin: -3px 0;
        overflow: auto hidden;
    }

    .tex-error {
        color: hsl(0deg 0% 50%);
    }

    /* Spoiler styling */
    .spoiler-block {
        border: hsl(0deg 0% 50%) 1px solid;
        padding: 2px 8px 2px 10px;
        border-radius: 10px;
        /* Space any subsequent Markdown content the same
           distance as adjacent paragraphs are spaced. */
        margin: 0 0 var(--markdown-interelement-doubled-space-px);

        .spoiler-header {
            /* We use flexbox to display the spoiler message
               and button. */
            display: flex;
            align-items: center;
            padding: 8px 5px;
            font-weight: bold;

            > :not(.spoiler-button) {
                /* Disallow margin from ordinary rendered-markdown
                   elements. The header's vertical space is handled
                   independently by padding on .spoiler-header. */
                margin-bottom: 0;
                /* Message grows to push the arrow to the right,
                   but shrinks so as to allow long multi-line
                   spoiler messages to wrap. */
                flex: 1 1 auto;
            }

            time {
                /* Time tag pushes the arrow out of view when overflow,
                   adding white-space property prevents this by wrapping
                   the element */
                white-space: normal;
            }
        }

        .spoiler-content {
            overflow: hidden;
            border-top: hsl(0deg 0% 50%) 0 solid;
            transition:
                height 0.4s ease-in-out,
                border-top 0.4s step-end,
                padding 0.4s step-end;
            padding: 0;
            height: 0;

            &.spoiler-content-open {
                border-top: hsl(0deg 0% 50%) 1px solid;
                transition:
                    height 0.4s ease-in-out,
                    border-top 0.4s step-start,
                    padding 0.4s step-start;
                padding: 5px;
                height: auto;
            }
        }

        .spoiler-button {
            /* Keep the button to a consistent right-hand edge. */
            padding-right: 3px;

            &:hover .spoiler-arrow {
                &::before,
                &::after {
                    background-color: hsl(0deg 0% 50%);
                }
            }
        }

        .spoiler-arrow {
            float: right;
            width: 15px;
            cursor: pointer;
            transition: 0.4s ease;
            transform: rotate(45deg);

            &::before,
            &::after {
                position: absolute;
                content: "";
                display: inline-block;
                width: 12px;
                height: 3px;
                background-color: hsl(0deg 0% 83%);
                transition: 0.4s ease;
            }

            &::after {
                position: absolute;
                transform: rotate(90deg);
                top: -5px;
                left: 5px;
            }

            &.spoiler-button-open {
                transform: rotate(45deg) translate(-5px, -5px);

                &::before {
                    transform: translate(10px, 0);
                }

                &::after {
                    transform: rotate(90deg) translate(10px, 0);
                }
            }
        }
    }

    /* embedded link previews */
    .message_inline_image_title {
        font-weight: bold;
    }

    .twitter-image,
    .message_inline_image {
        position: relative;
        margin-bottom: var(--markdown-interelement-space-px);
        margin-right: 5px;

        /* Sizing CSS for inline images requires care, because images load
           asynchronously, and browsers will unfortunately jump your
           scroll position when elements load above the current
           position in the message feed in a way that changes the
           height of elements. (As of March 2022, both Firefox and
           Chrome exhibit this problem, though in Chrome it is pretty
           subtle).

           We prevent this by setting a fixed height for inline
           previews. 100px is chosen because we don't want images to
           overwhelm conversation in message feeds, as it does in chat
           tools that show images at half-screen height or larger.

           If there are several images next to each other, we display
           them in a grid format; the same considerations requires
           that either use a scrollable region or set a fixed width
           for images so that the browser statically knows whether
           it'll need to overflow. We choose fixed width here. */
        height: 100px;
        width: 150px;

        /* Inline image containers also need an inline-block display in order
           to implement the desired grid layout. */
        display: inline-block;

        /* Set a background for the image; the background will be visible for
           messages whose aspect ratio is different from that of this
           container. */
        border: solid 1px transparent;
        transition: background 0.3s ease;
        background: hsl(0deg 0% 0% / 3%);

        &:hover {
            background: hsl(0deg 0% 0% / 15%);
        }

        & a {
            display: block;
            height: 100%;
            width: 100%;
        }

        img.image-loading-placeholder {
            content: url("../images/loading/loader-black.svg");
        }
    }

    &.rtl .twitter-image,
    &.rtl .message_inline_image {
        margin-left: unset;
        margin-right: 5px;
    }

    /* In browsers that support `:has()`, we pull
       `.rendered_markdown` out of the baseline group
       formed with EDITED/MOVED markers and the
       timestamp when the first child of the rendered
       markdown is a horizontal rule, a media element,
       or KaTeX. */
    &:has(> hr:first-child),
    &:has(> .message_inline_image:first-child),
    &:has(> p:first-child > .katex-display) {
        align-self: center;
    }

    /* But for browsers that don't support :has(),
       we provide a small layout hack using an
       inline grid. */
    @supports not selector(:has(*)) {
        p:first-child > .katex-display {
            /* KaTeX should take up 100% of the message box,
               so that KaTeX's own CSS for centering still works. */
            width: 100%;
        }

        p:first-child > .katex-display,
        .message_inline_image {
            /* We'll display this bit of media as
               an inline grid. That will allow us
               to put beneath the image a piece of
               invisible ::before content that we'll
               generate to participate in the
               messagebox-content grid's baseline
               group. */
            display: inline-grid;
            /* We create a grid area called
               "media", so that both the inner
               <a> element and the ::before content
               can sit there. `auto` will take on
               the height and width otherwise assigned
               to the .message_inline_image. Setting
               the min value to 0 on minmax() ensures
               that media larger than those dimensions
               don't cause a grid blowout. */
            grid-template: "media" minmax(0, auto) / minmax(0, auto);
        }

        p:first-child > .katex-display > .katex,
        .message_inline_image a,
        .message_inline_image video {
            /* We explicitly place the containing
               media element in the thumbnail area. */
            grid-area: media;
        }

        p:first-child > .katex-display::before,
        .message_inline_image::before {
            /* We generate a single . here to create
               text content enough for a baseline.
               Generated content is not generally
               read aloud to screen readers. */
            content: ".";
            /* We color the generated . transparently,
               so it won't be visible when the media
               doesn't cover the entire area. */
            color: transparent;
            /* And we explicitly place the . in the thumbnail
               area, too. Otherwise, grid would generate a new
               column track for it to sit in. */
            grid-area: media;
        }
    }

    .twitter-tweet {
        border: 1px solid hsl(0deg 0% 87%);
        padding: 0.5em 0.75em;
        margin-bottom: 0.25em;
        word-break: break-word;
        min-height: 48px;
    }

    .twitter-avatar {
        float: left;
        width: 48px;
        height: 48px;
        margin-right: 0.75em;
    }

    .message_inline_ref {
        margin-bottom: var(--markdown-interelement-space-px);
        margin-left: 5px;
        height: 50px;
        display: block !important;
        border: none !important;
    }

    &.rtl .message_inline_ref {
        margin-left: unset;
        margin-right: 5px;
    }

    .twitter-image img,
    .message_inline_image img,
    .message_inline_ref img {
        /* We use `scale-down` so that images smaller than the container are
           neither scaled up nor cropped to fit. This preserves
           their aspect ratio, which is often helpful. */
        object-fit: scale-down;

        /* We need to explicitly specify the image dimensions to have
           object-fit work; likely because internally object-fit needs
           to know the frame it is targeting, and images don't default
           to container dimensions. */
        height: 100%;
        width: 100%;

        float: left;
        margin-right: 10px;
        border-radius: inherit;
    }

    .message_inline_image img {
        cursor: zoom-in;
    }

    .youtube-video img,
    .vimeo-video img,
    .embed-video img {
        cursor: pointer;
    }

    &.rtl .twitter-image img,
    &.rtl .message_inline_image img,
    &.rtl .message_inline_ref img {
        float: right;
        margin-right: unset;
        margin-left: 10px;
    }

    & li .message_inline_image img {
        float: none;
    }

    .message_inline_video,
    .message_inline_animated_image_still {
        &:hover {
            &::after {
                transform: scale(1);
                transition: transform 0.2s;
            }
        }

        &::after {
            content: "";
            background-image: url("../images/play_button.svg");
            display: block;
            width: 32px;
            height: 32px;
            position: absolute;
            /* video width (100px) / 2 - icon width (32px) / 2 */
            top: 34px;
            /* video height (150px) / 2 - icon height (32px) / 2 */
            left: 59px;
            border-radius: 100%;
            transform: scale(0.8);
        }

        & video {
            display: block;
            object-fit: contain;
            height: 100%;
            width: 100%;
        }
    }

    .youtube-video .fa-play::before,
    .embed-video .fa-play::before {
        position: absolute;
        margin: var(--margin-top, 32px) 0 0 var(--margin-left, 45px);
        padding: 5px 8px 5px 10px;
        font-size: 12px;
        border-radius: 4px;
        background-color: hsl(0deg 0% 0%);
        color: hsl(0deg 0% 100%);
        opacity: 0.7;
        top: 0;
        left: 0;
    }

    .message_embed {
        display: block;
        position: relative;
        margin: 0 0 var(--markdown-interelement-space-px);
        border: none;
        border-left: 3px solid hsl(0deg 0% 93%);
        height: 80px;
        padding: 5px;
        z-index: 1;
        text-shadow: hsl(0deg 0% 0% / 1%) 0 0 1px;

        .message_embed_title {
            padding-top: 0;
            /* to remove the spacing that the font has from the top of the container. */
            margin-top: -5px;

            font-size: 1.2em;
            line-height: normal;
        }

        .message_embed_description {
            position: relative;
            max-width: 500px;
            margin-top: 3px;

            /* to put it below the container gradient. */
            z-index: -1;
        }

        .message_embed_image {
            display: inline-block;
            padding: 5px;
            width: 70px;
            height: 70px;
            background-size: cover;
            background-position: center;
        }

        .data-container {
            position: relative;
            padding: 0 5px;
            display: inline-block;
            vertical-align: top;
            max-width: calc(100% - 115px);
            max-height: 80px;
            overflow: hidden;
        }

        .data-container div {
            display: block;
            border: none;
        }

        .data-container::after {
            content: " ";
            position: absolute;
            width: 100%;
            height: 10%;
            bottom: 0;

            background: linear-gradient(
                0deg,
                var(--color-background-stream-message-content),
                transparent 100%
            );
        }
    }

    &.rtl .message_embed {
        border-left: unset;
        border-right: 3px solid hsl(0deg 0% 93%);
    }

    & a {
        color: var(--color-markdown-link);
        text-decoration: none;

        & code {
            color: var(--color-markdown-code-link);
        }

        &:hover,
        &:focus {
            color: var(--color-markdown-link-hover);
            text-decoration: underline;

            & code {
                color: var(--color-markdown-code-link-hover);
            }
        }
    }

    & pre {
        direction: ltr;
        /* code block text is a bit smaller than normal text */
        font-size: 0.825em;
        line-height: 1.4;
        white-space: pre;
        overflow-x: auto;
        word-break: break-all;
        word-wrap: normal;
        margin: 0 0 var(--markdown-interelement-space-px);
        padding: 5px 7px 3px;
        display: block;
        border-radius: 4px;

        &:hover .code-buttons-container {
            visibility: visible;
        }
    }

    & pre code {
        font-size: inherit;
        padding: 0;
        white-space: inherit;
        overflow-x: scroll;
        /* Unset to avoid compounding alpha values */
        background-color: unset;
        color: inherit;
        border: 0;
    }

    & code {
        /* 11.55px when body is the default 14px; this is chosen to be
        slightly above the 11.5px threshold where the height jumps by a
        pixel on most platforms. */
        font-size: 0.825em;
        unicode-bidi: embed;
        direction: ltr;
        white-space: pre-wrap;
        padding: 1px 2px;
        color: var(--color-markdown-code-text);
        background-color: var(--color-markdown-code-background);
        border-radius: 3px;
    }

    /* Container for buttons inside code blocks. */
    .code-buttons-container {
        /* Break white-space treatment inherited from <pre> */
        white-space: collapse;
        /* Present buttons in a flexbox layout. */
        display: flex;
        align-items: center;
        gap: 3px;
        /* Having absolute positioning here ensures that the element
        doesn't scroll along with the code div in narrow windows */
        position: absolute;
        top: 2px;
        right: 0;
        padding: 0 4px;
        /* Invisible unless <pre> is hovered. */
        visibility: hidden;
        z-index: 0;

        &::after {
            content: " ";
            position: absolute;
            height: 100%;
            width: 100%;
            z-index: -1;
            /* Blur the background behind the button container */
            backdrop-filter: blur(5px);
            /* Use a radial gradient to avoid obvious hard edges
               to the blur. */
            mask-image: radial-gradient(
                farthest-corner,
                hsl(0deg 0% 0% / 100%),
                hsl(0deg 0% 0% / 50%)
            );
        }

        #clipboard_image {
            /* Zero out legacy negative margins */
            margin: 0;
        }
    }

    /* Style copy-to-clipboard button inside code blocks */
    .copy_codeblock {
        display: flex;
        align-content: center;
        /* Push back on legacy styles from .copy_button_base,
           which are not necessary in the flex setting established
           on the .code-buttons-container. */
        height: auto;
        width: auto;
        background-clip: unset;
        /* Don't let the default button color appear
           behind the icon. Regrettably, !important
           is necessary for a thorny selector-specificity
           issue in dark mode. */
        background-color: transparent !important;
        /* Square off the box around the copy-to-clipboard icon. */
        padding: 0 2px 0 4px;

        &:hover {
            /* Regrettably, !important is necessary for a thorny
               selector-specificity issue in dark mode. */
            background-color: transparent !important;
        }

        /* Remove the outline when clicking on the copy-to-clipboard button */
        &:focus {
            outline: none;
        }
    }

    .code_external_link {
        /* Match the apparent size of the playground icon
           to the copy-to-clipboard icon. */
        font-size: 16px;
        /* Center the icon vertically in the link container. */
        display: flex;
        align-content: center;
        /* The font-icon footprint still requires 2px of
           top padding to get better alignment with the
           copy-to-clipboard icon. */
        padding-top: 2px;
        /* The default icon and on-hover colors are inherited from <a> tag.
        so we set our own to match the copy-to-clipbord icon */
        color: hsl(0deg 0% 47%);

        &:hover {
            color: hsl(200deg 100% 40%);
            text-decoration: none;
        }
    }
}

.group_mention,
.direct_mention {
    & .rendered_markdown pre {
        background-color: var(--color-markdown-pre-background-mentions);
        border-color: var(--color-markdown-pre-border-mentions);
    }

    & .rendered_markdown code {
        background-color: var(--color-markdown-code-background-mentions);
    }

    & .rendered_markdown pre code {
        background-color: unset;
        border-color: unset;
    }
}

.preview_content .copy_codeblock {
    /* We avoid displaying copy_codeblock button in previews, because it
       feels odd given that you can just copy-paste the code out of
       the "edit" state.  We may change this decision when we add
       menu options for viewing the code in a coding playground. */
    display: none;
}

.informational-overlays .copy_codeblock {
    display: none;
}

.message_edit_history_content .copy_codeblock {
    /*  Copy code block button is hidden in edit history, this is done
        because of issues faced in copying code blocks in edit history
        modal. This may be changed later as we decide upon a proper ux
        for displaying edit-history. */
    display: none;
}

.message_edit_history_content .code_external_link {
    right: 5px;
}

.preview_content .code_external_link {
    right: 12px;
}

@media (width < $sm_min) {
    .rendered_markdown .message_embed {
        height: auto;

        .message_embed_image {
            width: 100%;
            height: 100px;
        }

        .data-container {
            display: block;
            max-width: 100%;
            margin-top: 10px;
        }
    }
}

.codehilite {
    display: block !important;
    border: none !important;
    background: none !important;

    /* Set a relative positioning context to more precisely
       position .code-buttons-container. This eliminates
       problems with positioning shifts associated with
       code blocks in spoilers, too. */
    position: relative;

    & pre {
        color: var(--color-markdown-pre-text);
        /* This is necessary to remove the background color
           set by Pygments. */
        background-color: var(--color-markdown-pre-background);
        border: 1px solid var(--color-markdown-pre-border);
    }
}

/* Both the horizontal scrollbar in <pre/> as well as
   vertical scrollbar in the <textarea/> is styled similarly. */
.message_edit_form textarea,
.rendered_markdown pre {
    /* Ensure the horizontal scrollbar is visible on Mac */
    &::-webkit-scrollbar {
        height: 8px;
        width: 10px;
        background-color: hsl(0deg 0% 0% / 5%);
    }

    &::-webkit-scrollbar-thumb {
        background-color: hsl(0deg 0% 0% / 30%);
        border-radius: 20px;
        transition: all 0.2s ease;
    }

    &::-webkit-scrollbar-thumb:hover {
        background-color: hsl(0deg 0% 0% / 60%);
    }
}

/* Search highlight used in both topics and rendered_markdown */
.highlight {
    background-color: hsl(51deg 100% 79%);
}

/* For elements where we want to show as much markdown content we can
   in a single line and then hide the overflowing part. */
.single-line-rendered-markdown {
    /* Any element which can `wrap` in the above defined elements. */
    code,
    .stream-topic {
        white-space: nowrap;
    }
}
